package com.wstuo.common.jbpm;

import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jbpm.api.ProcessDefinition;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.history.HistoryProcessInstance;
import org.jbpm.api.identity.User;
import org.jbpm.api.model.ActivityCoordinates;
import org.jbpm.api.task.Task;
import org.springframework.transaction.annotation.Transactional;

import com.wstuo.common.bpm.dto.ActivityCoordinatesDTO;
import com.wstuo.common.bpm.dto.FlowPropertyDTO;
import com.wstuo.common.bpm.dto.HistoryTaskDTO;
import com.wstuo.common.bpm.dto.ProcessDefinitionDTO;
import com.wstuo.common.bpm.dto.ProcessDetailDTO;
import com.wstuo.common.bpm.dto.ProcessHistoriesDTO;
import com.wstuo.common.bpm.dto.ProcessHistoriesQueryDTO;
import com.wstuo.common.bpm.dto.ProcessInstanceDTO;
import com.wstuo.common.bpm.dto.TaskDTO;
import com.wstuo.common.dto.PageDTO;

public interface IJbpmFacade {

	/**
	 * 布署流程(ZIP) Deploy a process definition zip file into the process Repository
	 * 
	 * @param file
	 *            the given zip file
	 * @return a deployement ID
	 */
	@Transactional
	public abstract String deployJpdl(File file);

	/**
	 * 布署ZIP文件格式流程 Deploy a process definition zip file into the process Repository
	 * 
	 * @param fis
	 *            the zip file includes jpdl file and png file
	 * @return a deployement ID
	 */
	@Transactional
	public abstract String deployJpdl(InputStream fis);

	/**
	 * find process definition id by deployment Id
	 * 
	 * @param deploymentId
	 * @return process definition id
	 */
	public abstract String findProcessDefinitionIdByDeploymentId(String deploymentId);

	/**
	 * 根据deploymentId流程删除 Undeploy a process definition from the process repository
	 * 
	 * @param deploymentId
	 *            the given deploymentId
	 */
	public abstract void undeployJpdl(String deploymentId);

	/**
	 * 根据PID删除指定流程
	 * 
	 * @param pid
	 */
	public abstract void undeployJpdlById(String pid);

	/**
	 * 查询所有流程 Retrieves all of the latest version of process definitions from the process repository
	 * 
	 * @return all of the latest version of process definitions
	 */
	public abstract List<ProcessDefinition> findLatestProcessDefinitions();

	/**
	 * 分页查询流程
	 * 
	 * @param start
	 * @param limit
	 * @return PageDTO
	 */
	public abstract PageDTO findLatestProcessDefinitions(ProcessDefinitionDTO qdto, int start, int limit, String sord, String sidx);

	/**
	 * 流程实体转DTO
	 * 
	 * @param entity
	 * @return ProcessDefinitionDTO
	 */
	public abstract ProcessDefinitionDTO processDefinition2Dto(ProcessDefinition entity);

	/**
	 * 查看流程跟踪，返回image inputstream Retrieves the process image inputstream from the designated process definition
	 * 
	 * @param processDeploymentId
	 *            the designated process definition ID
	 * @return the process image inputstream
	 */
	public abstract InputStream getProcessImageByDeploymentId(String processDeploymentId);

	/**
	 * 查看流程跟踪，返回image inputstream Retrieves the process image inputstream from the designated process definition
	 * 
	 * @param processId
	 *            the designated process definition ID
	 * @return the process image inputstream
	 */
	public abstract InputStream getProcessImage(String processId);
	
	public abstract String getProcessXml(String processId);

	/**
	 * 根据PID查询所有流程实例 Retrieves all process instances belonged to the given process definition
	 * 
	 * @param pid
	 *            the process definition ID
	 * @return all process instances belonged to the given process definition
	 */
	public abstract List<ProcessInstance> findInstancesByProcessId(String pid);

	/**
	 * 根据PID分页查询流程实例
	 * 
	 * @param processDefinitionId
	 * @param start
	 * @param limit
	 *            is page size
	 * @return PageDTO
	 */
	public abstract PageDTO findInstances(String processDefinitionId, int start, int limit);

	/**
	 * 流程实例 TO DTO Instance TO DTO
	 * 
	 * @param entity
	 * @return ProcessInstanceDTO
	 */
	public abstract ProcessInstanceDTO processInstance2Dto(ProcessInstance entity);

	/**
	 * 根据实例ID查找流程实例 Get the process instance by ID
	 * 
	 * @param instanceId
	 *            process instance ID
	 * @return the process instance
	 */
	public abstract ProcessInstance getInstanceById(String instanceId);

	/**
	 * 启动流程实例并执行下一活动 Starts a process instance with the given variables
	 * 
	 * @param processKey
	 *            the process definition key
	 * @param variables
	 *            the given variables
	 */
	public abstract ProcessInstance startProcessByKey(String processKey, Map<String, Object> variables);

	/**
	 * 启动流程实例和执行下一活动
	 * 
	 * @param key
	 * @param variables
	 * @return the process instance id.
	 */
	public abstract String startProcessAndNext(String key, Map<String, Object> variables);

	/**
	 * 根据流程定义ID启动流程实例 Starts a process instance with the given variables
	 * 
	 * @param processDefinitionId
	 *            the process definition key
	 * @param variables
	 *            the given variables
	 */
	public abstract ProcessInstance startProcessByDefinitionId(String processDefinitionId, Map<String, Object> variables);

	/**
	 * 启动流程实例和执行下一活动
	 * 
	 * @param processType
	 *            value(ProcessKey or ProcessDefinitionId)
	 * @param value
	 * @param variables
	 * @return the process instance id.
	 */
	public abstract String startProcessAndNext(String processType, String value, Map<String, Object> variables);

	/**
	 * 根据流程实例执行下一活动 signal to the next execution of the process instance
	 * 
	 * @param pi
	 *            the given process instance;
	 */
	public abstract ProcessInstance signalNextExecution(ProcessInstance pi);

	/**
	 * 结束流程实例
	 * 
	 * @param pid
	 *            process instance id
	 */
	public abstract void endProcessInstance(String pid);

	/**
	 * 根据流程实例获取当前流程活动
	 * 
	 * @param processInstance
	 * @return 流程活动Set<String>
	 */
	public abstract Set<String> getActivityNamesByInstance(ProcessInstance processInstance);

	/**
	 * 检索指定的流程实例的活动坐标 Retrieves the activity coordinates of the designated process Instance
	 * 
	 * @param processInstance
	 *            the designated process instance
	 * @return the activity coordinates of the designated process Instance
	 */
	public abstract ActivityCoordinates getActivityCoordinatesByInstance(ProcessInstance processInstance);

	/**
	 * 检索历史的流程实例的活动坐标
	 * 
	 * @param processId
	 * @return 历史流程活动坐标List<ActivityCoordinatesDTO>
	 */
	public abstract List<ActivityCoordinatesDTO> getHistoryActivityCoordinatesByInstance(String processId);

	/**
	 * 检索所以历史流程实例 Retrieves all history process instances
	 * 
	 * @return all history process instances
	 */
	public abstract List<HistoryProcessInstance> findHistories();

	/**
	 * 分页查询历史流程实例 Retrieves all history process instances
	 * 
	 * @return all history process instances with find page
	 */
	public abstract PageDTO findPageHistories(ProcessHistoriesQueryDTO dto, int start, int limit);

	/**
	 * 查询历史实例
	 * 
	 * @param pid
	 *            流程实例ID
	 * @return 流程历史实例DTO
	 */
	public abstract ProcessHistoriesDTO findHistoryProcessInstanceByPid(String pid);

	/**
	 * ENTITY TO DTO
	 * 
	 * @param entity
	 *            历史流程实例实例类
	 * @return 流程历史实例DTO
	 */
	public abstract ProcessHistoriesDTO processHistories2Dto(HistoryProcessInstance entity);

	/**
	 * 根据用户查找所有任务 find tasks by given username
	 * 
	 * @param username
	 *            user name
	 * @return the tasks belonged to the given user
	 */
	public abstract List<Task> findTasks(String username);

	/**
	 * Task实体转DTO
	 * 
	 * @param task
	 *            任务实体类
	 * @return 任务DTO类
	 */
	public abstract TaskDTO task2Dto(Task task);

	/**
	 * 获取我的全部任务
	 * 
	 * @param username
	 * @return my all task with find page
	 */
	public abstract List<TaskDTO> findTaskDtos(String username);

	/**
	 * 分页查询指派给我的全部任务
	 * 
	 * @param username
	 * @return PageDTO
	 */
	public abstract PageDTO findTaskDtos(String username, int start, int limit);

	/**
	 * 分页查询指派给我组的全部任
	 * 
	 * @param username
	 * @return PageDTO
	 */
	public abstract PageDTO findGroupTaskDtos(String username, int start, int limit);

	/**
	 * 查询指派给某组的任务
	 * 
	 * @param userId
	 * @return List<Task>
	 */
	public abstract List<Task> findGroupTasks(String userId);

	/**
	 * 查询指派给某用户的任务
	 * 
	 * @param userId
	 * @return PageDTO
	 */
	public abstract PageDTO findPersonalTasks(String userId, int start, int limit);

	/**
	 * 统计指派指定用户的任务
	 * 
	 * @param userId
	 * @return 统计结果
	 */
	public abstract int countPersonalTasks(String userId);

	/**
	 * 任务完成并转到下一任务
	 * 
	 * @param taskId
	 *            任务ID
	 * @param username
	 *            指派用户
	 * @param to
	 *            流程出口
	 */
	public abstract void takeTask(String taskId, String username, String to);

	/**
	 * 任务完成并转到下一任务
	 * 
	 * @param pid
	 * @param activityName
	 * @param username
	 * @param to
	 */
	public abstract void takeTask(String pid, String activityName, String username, String to);

	/**
	 * 提取任务
	 * 
	 * @param taskId
	 * @param username
	 */
	public abstract void taskTask(String taskId, String username);

	/**
	 * 任务分配
	 * 
	 * @param taskId
	 * @param username
	 */
	public abstract void assignTask(String taskId, String username);

	/**
	 * 指派代理组
	 * 
	 * @param taskId
	 * @param groupId
	 * @param participationType
	 */
	public abstract void addTaskParticipatingGroup(String taskId, String groupId, String participationType);

	/**
	 * 指派代理人
	 * 
	 * @param taskId
	 * @param groupId
	 * @param participationType
	 */
	public void addTaskParticipatingUser(String taskId, String userId, String participationType) ;
	/**
	 * 获取当前任务
	 * 
	 * @param pid
	 * @param activityName
	 * @return task id
	 */
	public abstract String getTaskId(String pid, String activityName);

	/**
	 * 根据PID和活动获取所有任务
	 * 
	 * @param pid
	 * @param activityName
	 * @return List<Task>
	 */
	public abstract List<Task> findTaskByPidActivityName(String pid, String activityName);

	/**
	 * 获取当前活动指派给我的任务
	 * 
	 * @param processInstanceId
	 * @param userName
	 * @return List<TaskDTO>
	 */
	public abstract List<TaskDTO> getCurrentPiMyTask(String processInstanceId, String userName);

	/**
	 * 查询当前流程
	 * 
	 * @param pid
	 * @return List<TaskDTO>
	 */
	public abstract List<TaskDTO> findCurrentTaskByPid(String pid);

	/**
	 * 获取当前流程实例活动名称
	 * 
	 * @param pid
	 * @return process instance activity name
	 */
	public abstract String getActivityNameByPid(String pid);

	/**
	 * 分配活动
	 * 
	 * @param pid
	 * @param activityName
	 * @param username
	 */
	public abstract void assignActivity(String pid, String activityName, String username);

	/**
	 * 根据taskId,Variable key获取Variable Retrieves the variable value from a task with a given variable name
	 * 
	 * @param taskId
	 *            the designated task ID
	 * @param variableName
	 *            the variable name
	 * @return the variable value from a task
	 */
	public abstract Object getVariableByTaskId(String taskId, String variableName);

	/**
	 * 根据taskId获取Variable
	 * 
	 * @param taskId
	 * @return Map<String, Object>
	 */
	public abstract Map<String, Object> getVariablesByTaskId(String taskId);

	/**
	 * 根据taskId,executionId获取Variable
	 * 
	 * @param taskId
	 * @return Map<String, Object>
	 */
	public abstract Map<String, Object> getVariablesByExecutionId(String taskId, String executionId) throws Exception;

	/**
	 * 根据taskId获取task Retrieves the task of the given ID
	 * 
	 * @param taskId
	 *            the given task ID
	 * @return the task of the given ID
	 */
	public abstract Task getTask(String taskId);

	/**
	 * 查询所有JBPM用户
	 * 
	 * @return all jbpm user
	 */
	public abstract List<User> findUsers();

	/**
	 * Create Group 创建组
	 * 
	 * @param groupName
	 * @param parentGroupId
	 */
	@Transactional()
	public abstract void createGroup(String groupName, String parentGroupId);

	/**
	 * 创建用户
	 * 
	 * @param id
	 * @param familyName
	 * @param givenName
	 * @param businessEmail
	 */
	public abstract void createUser(String id, String familyName, String givenName, String businessEmail);

	/**
	 * 修改用户
	 * 
	 * @param id
	 * @param familyName
	 * @param givenName
	 * @param businessEmail
	 */
	public abstract void modifyUser(String id, String familyName, String givenName, String businessEmail);

	/**
	 * 添加用户与组关系
	 * 
	 * @param groupId
	 * @param parentGroupId
	 * @param userIds
	 */
	@Transactional()
	public abstract void createMembership(String groupId, String parentGroupId, String[] userIds);

	/**
	 * 据流程布署ID获取流程定义
	 * 
	 * @param deploymentId
	 * @return process definition
	 */
	public abstract ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId);

	/**
	 * 获取当前任务下的步骤
	 * 
	 * @param processInstanceId
	 * @return outcomes set
	 */
	public abstract Set<String> getOutcomes(String processInstanceId);

	/**
	 * 获取指定任务出口
	 * 
	 * @param taskId
	 * @return task outcome
	 */
	public abstract Set<String> findOutcomesByTaskId(String taskId);

	/**
	 * 根据PID获取当前task;
	 * 
	 * @param pid
	 * @return task
	 */
	public abstract Task getTaskByPid(String pid);

	/**
	 * 完成指定任务ID，并转到下一任务
	 * 
	 * @param taskId
	 * @param next
	 * @param variables
	 */
	public abstract void completeTask(String taskId, String next, Map<String, Object> variables);

	/**
	 * 任务完成
	 * 
	 * @param userId
	 * @param taskId
	 * @param next
	 * @param variables
	 */
	public abstract void completeTask(String userId, String taskId, String next, Map<String, Object> variables);

	/**
	 * 任务完成
	 * 
	 * @param taskId
	 * @param variables
	 */
	public abstract void completeTask(String taskId, Map<String, Object> variables);

	/**
	 * 任务完成
	 * 
	 * @param taskId
	 * @param next
	 */
	public abstract void completeTask(String taskId, String next);

	/**
	 * 任务完成
	 * 
	 * @param userId
	 * @param taskId
	 * @param next
	 */
	public abstract void completeTask(String userId, String taskId, String next);

	/**
	 * 任务完成
	 * 
	 * @param taskId
	 */
	public abstract void completeTask(String taskId);

	/**
	 * 根据流程实例获取历史任务
	 * 
	 * @param pid
	 * @return PageDTO
	 */
	public abstract PageDTO findHistoryTask(String pid, String assignee, int start, int limit);
	/**
	 * 获取历史任务中的技术员
	 * @param pid
	 * @param activityName 
	 * @return
	 */
	public abstract String findAssigneeByHistoryTask(ProcessInstance pi,String activityName);
	/**
	 * 根据流程实例获取历史任务
	 * 
	 * @param pid
	 * @return PageDTO
	 */
	public abstract HistoryTaskDTO findLastCompleteHistoryActivityInstance(String processInstanceId);

	/**
	 * 统计我已处理的任务
	 * 
	 * @param assignee
	 * @return count result
	 */
	public abstract Integer countGetPendingTasks(String assignee);

	/**
	 * 统计我已处理的任务
	 * 
	 * @param assignee
	 * @return count result
	 */
	public abstract Integer countMyProcessedTask(String assignee);

	/**
	 * 布署JPDL文件
	 * 
	 * @param jpdlfile
	 * @return deploy id
	 */
	@Transactional
	public abstract String deployJpdlXml(File jpdlfile);

	/**
	 * 获取当前流程下的所有节点
	 * 
	 * @param processDefinitionId
	 *            流程processDefinitionId值
	 * @return flow property dto
	 */
	@Transactional
	public abstract FlowPropertyDTO findProcessDefinitionActivity(String processDefinitionId);

	/**
	 * 根据当前实例ID获取当前流程活动的任务及出口
	 * 
	 * @param pid
	 * @return List<ProcessDetailDTO>
	 */
	public abstract List<ProcessDetailDTO> findProcessDetail(String pid);

	/**
	 * 根据PID、任务名称、出口查出下一个活动名称
	 * 
	 * @param pid
	 * @param taskName
	 * @param outcome
	 * @return process activity name
	 */
	public abstract String getNextActivity(String pid, String taskName, String outcome);

	/**
	 * 查询下一活动类型
	 * 
	 * @param pid
	 * @param activityName
	 * @param outcome
	 * @return 下一活动类型
	 */
	public abstract String getNextActivityType(String pid, String activityName, String outcome);

	/**
	 * 设置流程实例变量
	 * 
	 * @param pid
	 *            流程实例ID
	 * @param name
	 *            变量名称
	 * @param value
	 *            变量值
	 */
	public abstract void setInstanceVariable(String pid, String name, Object value);

	/**
	 * 设置流程实例变量
	 * 
	 * @param pid
	 * @param map
	 */
	public abstract void setInstanceVariables(String pid, Map<String, Object> map);

	/**
	 * 根据流程实例获取指定变量值
	 * 
	 * @param pid
	 * @param variableName
	 * @return variable object
	 */
	public abstract Object getInstanceVariables(String pid, String variableName);

	/**
	 * 获取流程实例变量名
	 * 
	 * @param pid
	 * @return variable name
	 */
	public abstract Set<String> getInstanceVariableNames(String pid);

	/**
	 * 获取流程实例全部变量
	 * 
	 * @param pid
	 * @param variableNames
	 * @return variables map
	 */
	public abstract Map<String, Object> getInstanceVariables(String pid, Set<String> variableNames);

	/**
	 * 设置任务变量
	 * 
	 * @param taskId
	 * @param variables
	 */
	public abstract void setTaskVariables(String taskId, Map<String, Object> variables);

	/**
	 * 获取任务变量
	 * 
	 * @param taskId
	 * @param variableName
	 * @return variable object
	 */
	public abstract Object getTaskVariable(String taskId, String variableName);

	/**
	 * 获取任务变量名称
	 * 
	 * @param taskId
	 * @return task variable name
	 */
	public abstract Set<String> getTaskVariableNames(String taskId);

	/**
	 * 获取任务变量值
	 * 
	 * @param taskId
	 * @param variableNames
	 * @return task variable value
	 */
	public abstract Map<String, Object> getTaskVariables(String taskId, Set<String> variableNames);

	/**
	 * 判断流程实例是否已结束
	 * 
	 * @param pid
	 * @return process instance end status
	 */
	public abstract boolean isEnded(String pid);

	/**
	 * 删除流程实例
	 * 
	 * @param pid
	 */
	public abstract void deleteProcessInstance(String pid);

	/**
	 * 删除流程实例(级联)
	 * 
	 * @param pid
	 */
	public abstract void deleteProcessInstanceCascade(String pid);

	/**
	 * 删除任务
	 * 
	 * @param taskId
	 */
	public abstract void deleteTask(String taskId);
}